/*=+--+=#=+--     Unmanned Aerial System Management Software      --+=#=+--+=#*\
|          Copyright (C) 2011 Regents of the University of Colorado.           |
|                             All Rights Reserved.                             |

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as
     published by the Free Software Foundation.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

            Jack Elston                       Cory Dixon                        
|           elstonj@colorado.edu              dixonc@colorado.edu              |
|                                                                              |
\*=+--+=#=+--                 --+=#=+--+=#=+--                    --+=#=+--+=#*/

/*!
	\file targetManager.cxx

	\author Jack Elston
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <vector>
#include <string>

#include "targetLayer.h"
#include "clientList.h"
#include "vcgui3.h"
#include "utilities.h"
#include "vcConfig.h"
#include "geoImage.h"

using namespace std; /*<---Global Variables---->*/
extern GuiStruct guiStr;
extern FifoMsg_t *fifo;

// TimeOut and colors
const char *targeted_color_str  = "blue";
const char *not_targeted_color_str = "white";

//---------------------------//

TargetManager::TargetManager()
{	
	resetFromZoom = false;
	numTargets = 0;
}

TargetManager::~TargetManager()
{	
}

void TargetManager::init(GPSMap *map)
{
	// init base class
	LayerManager::init(map);
	layerG = GOO_CANVAS_ITEM(gps_map->getLayerG(GPSMap::TARGET_LAYER));

	for(int i=0; i<NUM_TARGETS; i++) {
		targets[i].exists = false;
		targets[i].targeted = false;
	}
}

void TargetManager::create_canvas()
{
	canvas_created = true;

	// set the layer as active and shown
	gps_map->setLayerListShown( (GooCanvasItem *)GPSMap::TARGET_LAYER, true );
}

void TargetManager::updateMap()
{
}

void TargetManager::create_icon(TargetType_t *target, int number)
{

	// make sure parent manager layer is shown
	target->item = GOO_CANVAS_ITEM(goo_canvas_group_new(layerG,
				"x", 0.0,
				"y", 0.0,
				NULL));

	target->icon = goo_canvas_ellipse_new( target->item,
			0.0, 0.0,
			6.0, 6.0,
			"stroke-color", "black",
			"fill-color", not_targeted_color_str,
			"line-width", 2.0,
			NULL);

	gps_map->addLayer( "Target", target->item, (GooCanvasItem*)GPSMap::TARGET_LAYER);
	gps_map->setLayerListShown( target->item, true);
	gps_map->toggleLayerShown(GPSMap::TARGET_LAYER, true);
}

void TargetManager::update_icon(int number) 
{
	if( number < 0 || number >= NUM_TARGETS )
		return; 

	TargetType_t *target = &targets[number];

	//-- check for existence of target and icon
	if( !target->exists ) {
		cout << "TargetManager::update_icon -- no data for target " << number << endl;
		return;
	}

	if( !target->item ) {
		create_icon(target, number);
	}

	// stop any animation to get real position
	goo_canvas_item_stop_animation(target->item);

	//-- move icon 
	double x = target->telemetry.pos.lon;
	double y = target->telemetry.pos.lat;
	gps_map->geoToLayer(GPSMap::ICON_LAYER, x, y);

	//if( !gps_map->animateMotion() || resetFromZoom) {
		if( target->item )
			goo_canvas_item_set_simple_transform( target->item, x, y, 1.0, 0.0);
	/*} else {
		if( target->item )
			goo_canvas_item_animate(target->item,
					x, y,
					1.0, 0.0, TRUE,
					ANIMATION_TIME, ANIMATION_STEPS,
					GOO_CANVAS_ANIMATE_FREEZE);
	}*/

	//-- check data status
	TimeStamp currentTS;
	currentTS.stamp();

	if( target->targeted ) {
		g_object_set(G_OBJECT(target->icon), "fill-color", targeted_color_str, NULL);
	} else {
		g_object_set(G_OBJECT(target->icon), "fill-color", not_targeted_color_str, NULL);
	}
}

void TargetManager::translate_from_zoomChange(double zoom_factor)
{
	int i = 0;
	double x, y, scale, rot;

	//cout << " NodeIconManager::translate_from_zoomChange " << endl;

	// for icon group, its children are icons, consisting of different sub-children
	// such as text box and icon itself
	for( i=0; i < goo_canvas_item_get_n_children(layerG); i++ ) {

		// the next child is the icon items
		GooCanvasItem* child = goo_canvas_item_get_child(layerG, i);
		if( child ) {
			// stop any animation to get real position
			goo_canvas_item_stop_animation(child);

			goo_canvas_item_get_simple_transform(child, &x, &y, &scale, &rot);
			//cout << "x=" << x << " y=" << y << " scale=" << scale <<  " rot=" << rot << endl;
			goo_canvas_item_set_simple_transform( child, zoom_factor * x, zoom_factor * y, scale, 0.0);
		}
	}

	resetFromZoom = true;
	for(int v= 0; v < numTargets; v++ )
		update_icon(v);
	resetFromZoom = false;
}

bool TargetManager::received_data(int clientInd, uint8_t * buf) 
{
	TargetStatus_t * status = (TargetStatus_t *)(CMD_DATAPTR(buf));
	for(int i = 0; i< 4; i++) {
		targets[i].telemetry.pos.lat = status->targets[i].pos.lat;
		targets[i].telemetry.pos.lon = status->targets[i].pos.lon;
		targets[i].targeted = status->targets[i].targeted;
		targets[i].exists = true;
		update_icon(i);
	}
	return true;
}

bool TargetManager::setShown(int setTo)
{
	LayerManager::setShown(setTo);
	return true;
}
